use crate::{
    components::nestable::{Command, HierarchicalDragAndDrop, ItemTrait},
    core::message::{EditorMessage, GameObjectType, ObjectType, UiType},
    panel::UiPanelMessage,
};
use std::sync::{
    mpsc::{channel, Receiver, Sender},
    Arc,
};
use thunderdome::{Arena, Index};
use QcCore::{
    ecs::{components::light::LightType, game_object::GameObject},
    scene_system::{scene::Scene, scene_manager},
};
use QcUI::{component::Canvas, core::context::UiContext};

use crate::{components::dock::DockView, core::context::Context};

use super::LayerItem;

pub enum LayerPanelMessage {
    RebuildList,
}

#[derive(Debug)]
pub struct LayerPanel {
    context: Arc<Context>,
    list: HierarchicalDragAndDrop<LayerItem>,
    pub sender: Sender<LayerPanelMessage>,
    receiver: Receiver<LayerPanelMessage>,
    editor_sender: Sender<EditorMessage>,
}

impl DockView for LayerPanel {
    fn update(&mut self, ctx: &mut UiContext, show_tab: bool) {
        while let Ok(msg) = self.receiver.try_recv() {
            match msg {
                LayerPanelMessage::RebuildList => {
                    let mut scene_manager = self.context.scene_manager.try_write().unwrap();
                    let scene = scene_manager.get_current_scene_mut().unwrap();
                    let mut list = HierarchicalDragAndDrop::new(self.context.clone());

                    for obj in scene.children.iter() {
                        Self::build_layer(&mut list, scene, obj, self.list.root_id);
                    }

                    self.list = list;
                }
            }
        }
    }

    fn render(&mut self, ctx: &mut UiContext, show_tab: bool) {
        let context = self.context.clone();
        egui::Frame::none()
            .outer_margin(egui::Margin::same(8.))
            .show(ctx.ui, |ui| {
                ui.set_width(ui.available_width());
                ui.set_height(ui.available_height());
                ui.interact(ui.clip_rect(), ui.id(), egui::Sense::click())
                    .context_menu(|ui| {
                        ui.menu_button("创建", |ui| {
                            let message_center = self.context.message_center.try_read().unwrap();

                            let res = ui.button("空节点");
                            if res.clicked() {
                                self.editor_sender
                                    .send(EditorMessage::AddGameObject(GameObjectType::None))
                                    .unwrap();
                                self.after_created(ui);
                            }
                            ui.menu_button("游戏对象", |ui| {
                                ui.vertical(|ui| {
                                    let mut obj = None;
                                    if ui.button("平面").clicked() {
                                        obj = Some(GameObjectType::Plane);
                                    }
                                    if ui.button("立方体").clicked() {
                                        obj = Some(GameObjectType::Cube);
                                    }
                                    if ui.button("球").clicked() {
                                        obj = Some(GameObjectType::Ball);
                                    }
                                    if ui.button("胶囊").clicked() {
                                        obj = Some(GameObjectType::Capsule);
                                    }
                                    if ui.button("猴头").clicked() {
                                        obj = Some(GameObjectType::Monkey);
                                    }

                                    if let Some(obj) = obj {
                                        self.editor_sender
                                            .send(EditorMessage::AddGameObject(obj))
                                            .unwrap();
                                        self.after_created(ui);
                                    }
                                })
                            });
                            ui.menu_button("UI组件", |ui| {
                                message_center.send_to_ui_panel(UiPanelMessage::IsCapture(false));
                                ui.vertical(|ui| {
                                    let mut obj = None;
                                    if ui.button("Canvas").clicked() {
                                        self.editor_sender
                                            .send(EditorMessage::AddGameObject(
                                                GameObjectType::Canvas,
                                            ))
                                            .unwrap();
                                        self.after_created(ui);
                                    }
                                    if ui.button("按钮").clicked() {
                                        obj = Some(UiType::Button);
                                    }
                                    if ui.button("标签").clicked() {
                                        obj = Some(UiType::Label);
                                    }
                                    if ui.button("输入框").clicked() {
                                        obj = Some(UiType::TextBox);
                                    }
                                    if ui.button("布局").clicked() {
                                        obj = Some(UiType::Panel);
                                    }
                                    if ui.button("网格").clicked() {
                                        obj = Some(UiType::Grid);
                                    }
                                    if ui.button("单选框").clicked() {
                                        obj = Some(UiType::RadioBox);
                                    }
                                    if ui.button("多选框").clicked() {
                                        obj = Some(UiType::CheckBox);
                                    }

                                    if let Some(obj) = obj {
                                        self.editor_sender.send(EditorMessage::AddUi(obj)).unwrap();
                                        self.after_created(ui);
                                    }
                                })
                            });
                            ui.menu_button("灯光", |ui| {
                                ui.vertical(|ui| {
                                    let mut obj = None;
                                    if ui.button("点光源").clicked() {
                                        obj = Some(LightType::Point);
                                    }

                                    if ui.button("平行光").clicked() {
                                        obj = Some(LightType::Directional);
                                    }

                                    if ui.button("聚光灯").clicked() {
                                        obj = Some(LightType::Spot);
                                    }
                                    
                                    if ui.button("环境光").clicked() {
                                        obj = Some(LightType::AmbientBox);
                                    }

                                    if let Some(obj) = obj {
                                        self.editor_sender
                                            .send(EditorMessage::AddLight(obj))
                                            .unwrap();
                                        self.after_created(ui);
                                    }
                                })
                            });
                        });
                    });

                self.list.ui(ui, |command| {
                    match command {
                        Command::MoveItem {
                            moved_item_id,
                            target_container_id,
                            target_position_index,
                        } => {
                            let mut scene_manager = context.scene_manager.try_write().unwrap();
                            let scene = scene_manager.get_current_scene_mut().unwrap();

                            let new_parent = if target_container_id.get_id() == Index::DANGLING {
                                None
                            } else {
                                Some(target_container_id.get_id())
                            };

                            let child_id = moved_item_id.get_id();

                            if moved_item_id.obj_type == target_container_id.obj_type {
                                match target_container_id.obj_type {
                                    ObjectType::GameObject => {
                                        Self::move_game_object(scene, child_id, new_parent);
                                    }
                                    ObjectType::UiObject => {
                                        if let Some(index) = scene.get_main_canvas() {
                                            if let Some(canvas) =
                                                scene[index].getComponentMut::<Canvas>()
                                            {
                                                Self::move_ui_node(canvas, child_id, new_parent);
                                            }
                                        }
                                    }
                                }
                            } else if let Some(index) = scene
                                .get_main_canvas()
                                .filter(|canvas| *canvas == target_container_id.id)
                            // ui组件移动到Canvas下
                            {
                                if let Some(canvas) = scene[index].getComponentMut::<Canvas>() {
                                    Self::move_ui_node(canvas, child_id, new_parent);
                                }
                            } else {
                                return false;
                            }
                        }
                        Command::SetSelectedItem(item_id) => {
                            if let Some(item_id) = item_id {
                                let editor_actions = &context.editor_actions;
                                editor_actions.select_with_type(item_id.obj_type, Some(item_id.id));
                            }
                        }
                        _ => {}
                    };
                    true
                });
            });
    }
}

impl LayerPanel {
    pub fn new(context: Arc<Context>, editorSender: Sender<EditorMessage>) -> Self {
        let mut list = HierarchicalDragAndDrop::new(context.clone());

        let (sender, receiver) = channel();

        let mut scene_manager = context.scene_manager.try_write().unwrap();
        let scene = scene_manager.get_current_scene_mut().unwrap();

        let root_id = list.root_id;
        for obj in scene.children.iter() {
            Self::build_layer(&mut list, scene, obj, root_id);
        }

        let mut this = Self {
            context: context.clone(),
            list,
            sender,
            receiver,
            editor_sender: editorSender,
        };

        this
    }

    fn build_layer(
        list: &mut HierarchicalDragAndDrop<LayerItem>,
        scene: &Scene,
        index: &Index,
        item_id: LayerItem,
    ) {
        if let Some(obj) = scene.get(*index) {
            let item_id = list.add_container(item_id, obj.root.unwrap());
            for id in obj.children.iter() {
                Self::build_layer(list, scene, id, item_id);
            }

            if let Some(canvas) = scene.get_main_canvas().filter(|canvas| canvas == index) {
                let canvas = scene[canvas].getComponent::<Canvas>().unwrap();

                for id in canvas.children.iter() {
                    Self::build_ui_layer(list, canvas, id, item_id);
                }
            }
        }
    }

    // 显示 Canvas 中的 ui节点
    fn build_ui_layer(
        list: &mut HierarchicalDragAndDrop<LayerItem>,
        canvas: &Canvas,
        obj: &Index,
        item_id: LayerItem,
    ) {
        let widget = canvas[*obj].get_widget();

        let item_id = list.add_container_item(
            item_id,
            LayerItem::new(widget.id).with_type(ObjectType::UiObject),
        );

        for id in widget.children.iter() {
            Self::build_ui_layer(list, canvas, id, item_id);
        }
    }

    pub fn move_game_object(scene: &mut Scene, child_id: Index, new_parent: Option<Index>) {
        let child = &scene[child_id];

        let parent = child.parent;

        if parent != new_parent {
            scene.remove_child_with_parent(child_id, parent);

            scene.add_child_with_parent_by_id(child_id, new_parent);
        }
    }

    pub fn move_ui_node(canvas: &mut Canvas, child_id: Index, new_parent: Option<Index>) {
        let child = &canvas[child_id].get_widget_mut();

        let parent = child.parent;

        if parent != new_parent {
            canvas.remove_child_with_parent(child_id, parent);

            canvas.add_child_with_parent_by_id(child_id, new_parent);
        }
    }

    pub fn after_created(&self, ui: &mut egui::Ui) {
        self.sender.send(LayerPanelMessage::RebuildList).unwrap();
        let message_center = self.context.message_center.try_read().unwrap();

        message_center.send_to_ui_panel(UiPanelMessage::IsCapture(true));
        ui.close_menu();
    }
}
